/**
 * @Copyright:Copyright (c) 1992 - 2015
 * @Company: TengTong
 */
package com.tengtong.duang.commons.utils;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;


import com.tengtong.duang.commons.base.ClassFilter;
import com.tengtong.duang.commons.collections.ArrayWrapper;
import com.tengtong.duang.commons.test.DuangLogger;
import com.tengtong.duang.commons.utils.helper.AnnotationFilter;
import com.tengtong.duang.commons.utils.helper.InheritanceFilter;;

/**
 * class 查询工具集
 *
 * @author jai
 * @since: v1.0
 */
public class ClassQuery {

	/**
	 * 要查询的包路径（包名称），可以有多个
	 */
	private final String[] packageNames;
	
	/**
	 * 结果集，作为缓存使用
	 */
	private Set<Class<?>> buffers = new HashSet<Class<?>>();
	
	public ClassQuery(String packageName){
		this.packageNames = new String[]{packageName};
	}
	
	/**
	 * @param packageNames
	 */
	public ClassQuery(String[] packageNames) {
		this.packageNames = packageNames;
	}
	
	/**
	 * 通过判断 类是否定义了某个  Annotation 来筛选并得到结果集合
	 * 
	 * 即查询所有定义某个注解的类
	 *
	 * @param annotationClass
	 * @return
	 */
	public ClassQuery ifDefine(Class<? extends Annotation> annotationClass){
		if(annotationClass != null){
			try {
				ArrayWrapper.wrapper(packageNames)
							.forEach(packageName->{
								getAndAdds(packageName, new AnnotationFilter(annotationClass));
							});
			}
			catch (Exception e) {
				DuangLogger.error("[Dunang ClassQuery]==> Scan [" + Arrays.deepToString(packageNames) + "] Class Fail!, Excepiton:", e);
			}
		}
		return this;
	}
	
	/**
	 * 取所有类
	 *
	 * @return
	 */
	public void all(){
		try{
			ArrayWrapper.wrapper(packageNames)
						.forEach(packageName->{
							getAndAdds(packageName, null);
						});
		}catch(Exception e){
			DuangLogger.error("[Duang-Lang]==> Scan [" + Arrays.deepToString(packageNames) + "] Class Fail!, Excepiton:", e);
		}
	}

	/**
	 * 查找出所有 实现或继承 source 的类
	 *
	 * @param interfaceName
	 * @return
	 */
	public ClassQuery inheritance(Class<?> source){
		if(source == null)
			return this;
		
		try {
			ArrayWrapper.wrapper(packageNames)
						.forEach(packageName->{
							getAndAdds(packageName, new InheritanceFilter(source));
						});
		}
		catch (Exception e) {
			DuangLogger.error("[Duang-Lang]==> Scan [" + Arrays.deepToString(packageNames) + "] Class Fail!, Excepiton:", e);
		}
		
		return this;
	}
	
	/**
	 * 清除之前的数据集 （重置缓冲区）
	 *
	 * @return
	 */
	public ClassQuery clear(){
		buffers.clear();
		return this;
	}
	
	/**
	 * 获取数据
	 *
	 * @param pn
	 */
	private void getAndAdds(String pn, ClassFilter filter) {
		try{
			//逐个包来进行读取过滤
			buffers.addAll(PackageUtils.getClassesInPackage(pn, filter));
		}catch(Exception e){
			throw ReflectUtils.toRuntimeException(e);
		}
	}
	
	
}
